package com.czmh.etc.onlinepubsys.job;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.czmh.etc.common.core.utils.Sequence;
import com.czmh.etc.onlinepubsys.json.JsonResult;
import com.czmh.etc.onlinepubsys.json.cmg.JSONResult;
import com.czmh.etc.onlinepubsys.model.EtcDevice;
import com.czmh.etc.onlinepubsys.model.EtcPayOrder;
import com.czmh.etc.onlinepubsys.model.EtcReward;
import com.czmh.etc.onlinepubsys.model.SysConfig;
import com.czmh.etc.onlinepubsys.services.EtcPayOrderService;
import com.czmh.etc.onlinepubsys.services.EtcRewardService;
import com.czmh.etc.onlinepubsys.services.IDistributedLocker;
import com.czmh.etc.onlinepubsys.services.SysConfigService;
import com.czmh.etc.onlinepubsys.utils.DatetimeUtil;
import com.czmh.etc.onlinepubsys.utils.RedisUtil;
import com.czmh.etc.onlinepubsys.utils.mingchuang.PayUtil;
import com.foxinmy.weixin4j.pay.WeixinPayProxy;
import com.foxinmy.weixin4j.pay.model.WeixinPayAccount;
import com.foxinmy.weixin4j.pay.payment.mch.CorpPayment;
import com.foxinmy.weixin4j.pay.payment.mch.CorpPaymentResult;
import com.foxinmy.weixin4j.pay.type.mch.CorpPaymentCheckNameType;
import com.foxinmy.weixin4j.util.DateUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;

import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * Copyright (C), 2017-2021
 * Author: Chenzj
 * Date: 2021-11-11
 * FileName: DealUeActiveJob
 * Description: 处理订金退款定时任务
 */
@Slf4j
@Component
public class DealRefundJob {
    @Value("${wx.wxPayMch_id}")
    private String wxPayMchId;

    @Value("${wx.wxPayAppSecret}")
    private String wxPayAppSecret;

    @Value("${wx.wxPayAppid}")
    private String appId;

    @Autowired
    private RedisUtil redisUtil;

    @Autowired
    private IDistributedLocker distributedLocker;

    @Autowired
    private EtcPayOrderService etcPayOrderService;

    @Autowired
    private EtcRewardService etcRewardService;

    @Autowired
    private SysConfigService sysConfigService;

    @Scheduled(cron = "45 * * * * ? ")
    public void dealRefundJob() {
        //判断是否开启分布式定时任务
        Object enable = redisUtil.get("job:DealRefundJob:dealRefundJob");
        String key = "job-key:DealUeActiveJob:dealUeActive1";
        if (enable == null || enable.toString().equalsIgnoreCase("1")) {
            // 尝试获取锁，等待5秒，自己获得锁后一直不解锁则10秒后自动解锁
            boolean isGetLock = distributedLocker.tryLock(key, TimeUnit.SECONDS, 1L, 5L);
            if (isGetLock) {
                //获取符合条件的订单信息
                QueryWrapper<EtcPayOrder> queryWrapper = new QueryWrapper<>();
                LambdaQueryWrapper<EtcPayOrder> lambda = queryWrapper.lambda();
                lambda.eq(EtcPayOrder::getDeleteFlag, 0);
                lambda.in(EtcPayOrder::getPayState, 3, 8);
                List<EtcPayOrder> list = etcPayOrderService.list(queryWrapper);
                if (!CollectionUtils.isEmpty(list)) {
                    for (int i = 0; i < list.size(); i++) {
                        EtcPayOrder etcPayOrder = list.get(i);
                        try {
                            //全额微信原路退款
                            if(etcPayOrder.getType() == 2){
                                JsonResult result = etcPayOrderService.refundWxPayOrder(etcPayOrder.getOrderNo(), etcPayOrder.getUserId());
                                if (result.getCode().equals(JSONResult.SUCCESS)) {
                                    log.info("处理前置订金退款定时任务执行成功:{}", result);
                                }else{
                                    log.info("处理前置订金退款定时任务执行失败:{}", result);
                                }
                            }
                            //微信退款一部分
                            if(etcPayOrder.getType() == 1){
                                int refundAmount = 0;
                                SysConfig refundAmountConfig = sysConfigService.queryByKey("refund_amount");
                                if (refundAmountConfig != null && refundAmountConfig.getConfigValue() != null && StringUtils.isNotEmpty(refundAmountConfig.getConfigValue())) {
                                    String value = refundAmountConfig.getConfigValue();
                                    refundAmount = Integer.valueOf(value);
                                } else {
                                    log.error("请联系管理员完善退款金额配置！");
                                }
                                //查询是否存在同样的记录，不存在则新增付款记录并及时付款
                                Map<String, Object> q = new HashMap<>();
                                q.put("deleteFlag", "0");
                                q.put("productSn", etcPayOrder.getProductSn() + "@" + etcPayOrder.getOrderSn());
                                q.put("rewardType", "3");
                                int count = etcRewardService.queryTotal(q);
                                if (count < 1) {
                                    //首先插入一条为付款的数据
                                    Date date = new Date();
                                    EtcReward etcReward = new EtcReward();
                                    etcReward.setPayAmount(refundAmount);
                                    etcReward.setId(Sequence.getId());
                                    etcReward.setCity(etcPayOrder.getCity());
                                    etcReward.setCountry(etcPayOrder.getDetailAddress());
                                    etcReward.setProvince(etcPayOrder.getProvince());
                                    etcReward.setSubscribe(1);
                                    etcReward.setStatus(1);
                                    etcReward.setPayStatus(0);
                                    etcReward.setLanguage("zh_CN");
                                    etcReward.setDeleteFlag(0);
                                    etcReward.setRewardType(3);
                                    //使用OBU设备的序列号作为商户订单号
                                    etcReward.setOrderId(etcPayOrder.getOrderSn());
                                    etcReward.setSubscribeTime(date);
                                    etcReward.setUpdatedTime(etcReward.getUpdatedTime());
                                    etcReward.setName(etcPayOrder.getConsigneeName());
                                    etcReward.setPhone(etcPayOrder.getPhone());
                                    etcReward.setNickname(etcPayOrder.getNickName());
                                    etcReward.setSex(0);
                                    etcReward.setStoreAddress(etcPayOrder.getDetailAddress());
                                    etcReward.setOpenid(etcPayOrder.getOpenid());
                                    etcReward.setUnionid(etcPayOrder.getUnionid());
                                    etcReward.setHeadimgurl("");
                                    etcReward.setProductSn(etcPayOrder.getProductSn() + "@" + etcPayOrder.getOrderSn());
                                    etcReward.setCreateTime(date);
                                    etcReward.setUpdatedTime(date);
                                    etcReward.setRequestData("");
                                    etcReward.setRequestData(JSON.toJSONString(etcReward));
                                    int a = etcRewardService.save(etcReward);
                                    if (a > 0) {
                                        //插入未付款数据之后开始付款
                                        CorpPaymentResult corpPaymentResult = null;
                                        try {
                                            log.info(JSON.toJSONString(etcReward));
                                            corpPaymentResult = sendCorpPayment(null, etcReward);
                                            if (corpPaymentResult != null) {
                                                log.info(JSON.toJSONString(corpPaymentResult));
                                            }
                                        } catch (Exception e) {
                                            e.printStackTrace();
                                            etcReward.setJsonData(e.getMessage());
                                        }
                                        //付款失败之后把记录状态改成支付失败，后面允许再次支付
                                        if (corpPaymentResult == null) {
                                            etcReward.setPayStatus(3);
                                            etcReward.setUpdatedTime(new Date());
                                        } else if (corpPaymentResult != null && corpPaymentResult.getTransactionId() != null) {
                                            //微信付款成功之后改变记录的支付状态，同时更新记录的其他信息
                                            etcReward.setPaymentTime(DatetimeUtil.parseSQLDate(corpPaymentResult.getPaymentTime(), DatetimeUtil.STANDARD_DATETIME_PATTERN));
                                            etcReward.setPaymentNo(corpPaymentResult.getTransactionId());
                                            etcReward.setPayStatus(2);
                                            etcReward.setJsonData(JSON.toJSONString(corpPaymentResult));
                                            etcReward.setUpdatedTime(new Date());
                                            JSONObject json = JSON.parseObject(JSON.toJSONString(corpPaymentResult));
                                            json.put("payAmount", etcReward.getPayAmount());
                                            etcPayOrder.setPayState(7);
                                            //请求信息附加到扩展字段
                                            String jsonStr = etcPayOrder.getJsonData();
                                            JSONObject jsonObject = JSON.parseObject(jsonStr);
                                            if (jsonObject == null) {
                                                jsonObject = new JSONObject();
                                            }
                                            jsonObject.put("payRefundResponse", json);
                                            etcPayOrder.setJsonData(jsonObject.toJSONString());
                                            etcPayOrder.setRefundTime(etcReward.getPaymentTime());
                                            etcPayOrder.setRefundNo(corpPaymentResult.getTransactionId());
                                            etcPayOrderService.updateById(etcPayOrder);
                                            log.info((json.toJSONString()));
                                        } else {
                                            //支付失败之后把记录状态改成支付失败，后面允许再次支付
                                            etcReward.setJsonData(JSON.toJSONString(corpPaymentResult));
                                            etcReward.setPayStatus(3);
                                            etcReward.setUpdatedTime(new Date());
                                            log.info(JSON.toJSONString(corpPaymentResult));
                                        }
                                        //更新记录信息
                                        a = etcRewardService.update(etcReward);
                                    } else {
                                        //新增记录失败之后再手动删除对应的记录，避免脏数据
                                        etcRewardService.delete(etcReward.getId());
                                        log.info("奖励领取失败，请联系管理员！");
                                    }
                                }
                            }
                        } catch (Exception e) {
                            e.printStackTrace();
                            log.info("处理订金退款定时任务执行失败:{}", e.getMessage());
                        }
                    }
                }
            }
        }
    }

    public CorpPaymentResult sendCorpPayment(EtcDevice etcDevice, EtcReward etcReward) throws Exception {
        //转账描述
        String desc = "补贴通行费用";
        //调用接口的机器Ip地址
        String clientIp = PayUtil.getLocalIp();
        WeixinPayAccount weixinPayAccount = new WeixinPayAccount(appId, wxPayAppSecret, wxPayMchId);
        WeixinPayProxy weixinPayProxy = new WeixinPayProxy(weixinPayAccount);

        CorpPayment corpPayment = new CorpPayment(etcReward.getOrderId(), etcReward.getOpenid(), CorpPaymentCheckNameType.NO_CHECK, desc, DateUtil.formatFee2Yuan(etcReward.getPayAmount()), clientIp);
        log.info(JSON.toJSONString(corpPayment));
        CorpPaymentResult corpPaymentResult = weixinPayProxy.sendCorpPayment(corpPayment);
        log.info(JSON.toJSONString(corpPaymentResult));
        if (corpPaymentResult != null && StringUtils.isNotEmpty(corpPaymentResult.getTransactionId())) {
            //转账成功之后的代码逻辑
            return corpPaymentResult;
        } else {
            //转账失败之后的代码逻辑
            return corpPaymentResult;
        }
    }
}
